/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string')) {
      if ((/^[0-9]+$/.test(time))) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }

    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
  if (!search) {
    return {}
  }
  const obj = {}
  const searchArr = search.split('&')
  searchArr.forEach(v => {
    const index = v.indexOf('=')
    if (index !== -1) {
      const name = v.substring(0, index)
      const val = v.substring(index + 1, v.length)
      obj[name] = val
    }
  })
  return obj
}

/**
 * 去除对象中值为null、undefined、''的字段
 * @param {*} obj
 * @returns
 */
export function removeEmptyField(obj) {
  var newObj = {}
  if (typeof obj === 'string') {
    obj = JSON.parse(obj)
  }
  if (obj instanceof Array) {
    newObj = []
  }
  if (obj instanceof Object) {
    for (var attr in obj) {
      // eslint-disable-next-line no-prototype-builtins
      if (obj.hasOwnProperty(attr) && obj[attr] !== '' && obj[attr] !== null && obj[attr] !== undefined) {
        if (obj[attr] instanceof Object) {
          newObj[attr] = removeEmptyField(obj[attr])
        } else if (typeof obj[attr] === 'string' && ((obj[attr].indexOf('{') > -1 && obj[attr].indexOf('}') > -1) || (obj[attr].indexOf('[') > -1 && obj[attr].indexOf(']') > -1))) {
          try {
            var attrObj = JSON.parse(obj[attr])
            if (attrObj instanceof Object) {
              newObj[attr] = removeEmptyField(attrObj)
            }
          } catch (e) {
            newObj[attr] = obj[attr]
          }
        } else {
          newObj[attr] = obj[attr]
        }
      }
    }
  }
  return newObj
}

export function setArrayItem(key, value) {
  value = JSON.stringify(value)
  localStorage.setItem(key, value)
}

export function getArrayItem(key, defaultValue) {
  console.log(localStorage.getItem(key))
  if (localStorage.getItem(key)) {
    try {
      return JSON.parse(localStorage.getItem(key))
    } catch (err) {
      console.log(err)
      return []
    }
  }
  return defaultValue || []
}

export function convertArr2Obj(arr, key) {
  return arr.reduce((obj, v) => {
    obj[v[key]] = v
    return obj
  }, {})
}

export function convertArr2Objs(arr, key) {
  return arr.reduce((obj, v) => {
    if (!obj[v[key]]) {
      obj[v[key]] = [v]
    } else {
      obj[v[key]].push(v)
    }
    return obj
  }, {})
}

/**
 * 生成随机字符串
 * @param {*} length
 * @returns
 */
export function generateRandStr(length = 10) {
  let text = ''
  const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  for (var i = 0; i < length; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length))
  }

  return text
}

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr(arr) {
  return Array.from(new Set(arr))
}

export function clearCache() {
  const keys = ['intelirri-devices', 'intelirri-devicesObj', 'intelirri-currentDevice', 'intelirri-projects', 'intelirri-project']
  keys.forEach(item => {
    localStorage.removeItem(item)
  })
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'deepClone')
  }
  const targetObj = source.constructor === Array ? [] : {}
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys])
    } else {
      targetObj[keys] = source[keys]
    }
  })
  return targetObj
}

export function unique(arr) {
  return Array.from(new Set(arr))
}

// 获取当前时间
export function getCurrentTime() {
  const myDate = new Date()
  const myYear = myDate.getFullYear()
  const myMonth = myDate.getMonth() + 1
  const myToday = myDate.getDate()
  const myHour = myDate.getHours()
  const myMinute = myDate.getMinutes()
  const mySecond = myDate.getSeconds()

  return [myYear, fillZero(myMonth), fillZero(myToday)].join('-') + ' ' + [fillZero(myHour), fillZero(myMinute), fillZero(mySecond)].join(':')
}

function fillZero(str) {
  var realNum
  if (str < 10) {
    realNum = '0' + str
  } else {
    realNum = str
  }
  return realNum
}

export function isJson(str) {
  if (typeof str === 'string') {
    try {
      JSON.parse(str)
      return true
    } catch (e) {
      return false
    }
  }
}

export function arraySort(arr, namekey, order = 'desc') {
  if (order === 'desc') {
    return arr.sort((a, b) => {
      return b[namekey] - a[namekey]
    })
  }
  return arr.sort((a, b) => {
    return a[namekey] - b[namekey]
  })
}

/**
 * 计算时间差
 * @param {*} startTime
 * @param {*} endTime
 * @param {*} diffType
 * @returns
 */
export function getDateDiff(startTime, endTime, diffType) {
  // 将xxxx-xx-xx的时间格式，转换为 xxxx/xx/xx的格式
  startTime = startTime.replace(/\-/g, '/')
  endTime = endTime.replace(/\-/g, '/')

  // 将计算间隔类性字符转换为小写
  diffType = diffType.toLowerCase()
  var sTime = new Date(startTime) // 开始时间
  var eTime = new Date(endTime) // 结束时间
  // 作为除数的数字
  var divNum = 1
  switch (diffType) {
    case 'second':
      divNum = 1000
      break
    case 'minute':
      divNum = 1000 * 60
      break
    case 'hour':
      divNum = 1000 * 3600
      break
    case 'day':
      divNum = 1000 * 3600 * 24
      break
    default:
      break
  }
  return parseInt((eTime.getTime() - sTime.getTime()) / parseInt(divNum))
}

/**
 * 获取二级域名
 * @returns
 */
export function getDomain() {
  const url = window.location.href
  const h = url.split('.')[0]
  const a = h.split('//')[1]
  return a
}

/**
 * 根据指定属性键及字典获取属性
 * @param {*} value
 * @param {*} name
 * @param {*} datas
 * @returns
 */
export function getAttr(value, name, datas) {
  const datas_filter = convertArr2Obj(datas, name)
  return datas_filter[value].name || ''
}

/**
 * 给 el-table 每个字段设置默认值
 * @param {*} row
 * @param {*} column
 * @returns
 */
export function formatterForTable(row, column) {
  const properties = column.property.split('.')
  if (properties.length === 1) {
    return row[column.property] || '--'
  } else {
    const length = properties.length
    let result = row[properties[0]]
    for (let i = 1; i < length; i++) {
      result = result[properties[i]]
    }
    return result || '--'
  }
}

/**
 * 格式化数据为小数点后几位
 * @param {*} name
 * @param {*} data
 * @param {*} precision
 * @returns
 */
export function getFloatAttr(name, data, precision) {
  if (data && data[name]) {
    return (+data[name]).toFixed(precision)
  }
  return 0
}

/**
 * 获取当前日期
 * @returns
 */
export function getCurrentDate() {
  const dateObj = new Date()
  return [dateObj.getFullYear(), (dateObj.getMonth() + 1).toString().padStart(2, 0), dateObj.getDate().toString().padStart(2, 0)].join('-')
}

/**
 * 获取指定日期后的日期
 * @param {*} date
 * @param {*} day
 * @returns
 */
export function getNextDate(date, day = 14) {
  const dd = new Date(date)
  dd.setDate(dd.getDate() + day)
  return [dd.getFullYear(), (dd.getMonth() + 1).toString().padStart(2, 0), dd.getDate().toString().padStart(2, 0)].join('-')
}

export function getDaterange(daterange) {
  const startDate = new Date(daterange[0])
  const endDate = new Date(daterange[1])
  // 使用一个循环，从起始日期开始逐一增加日期，直到到达结束日期为止，并将每个日期添加到一个数组dateArray中。

  const dateArray = []
  const currentDate = startDate

  // eslint-disable-next-line no-unmodified-loop-condition
  while (currentDate <= endDate) {
    const dd = new Date(currentDate)
    dateArray.push([(dd.getMonth() + 1).toString().padStart(2, 0), dd.getDate().toString().padStart(2, 0)].join('-'))
    currentDate.setDate(currentDate.getDate() + 1)
  }

  return dateArray
}

/**
 * 格式化传输过来的分区数据
 * @param {*} cells
 * @returns
 */
export function formatCells(cells) {
  const saveId = []
  const saveData = []
  cells.forEach((el) => {
    const index = saveId.indexOf(el.id)
    if (index >= 0) {
      saveData[index].push(el)
    } else {
      saveId.push(el.id)
      saveData.push([el])
    }
  })
  // 2、还原分区
  const area = []
  saveData.forEach((el) => {
    const obj = {}
    obj.id = el[0].id
    obj.argstart = el[0].argstart
    obj.argend = el[0].argend
    obj.name = '管理区' + el[0].id
    obj.children = []
    el.forEach((item) => {
      obj.children.push({
        id: item.id + '' + item.idx,
        pid: item.id,
        idx: item.idx,
        name: '小分区' + item.idx,
        color: item.color,
        argstart: item.argstart,
        argend: item.argend,
        spstart: item.spstart,
        spend: item.spend,
        disstart: item.disstart,
        disend: item.disend,
        radius: item.disend
      })
    })
    area.push(obj)
  })

  return area
}

import * as turf from '@turf/turf'
export function getPoint(point, distance, bearing) {
  point = turf.point(point)
  var options = { units: 'kilometers' }

  var destination = turf.destination(point, distance / 1000, bearing, options)
  return destination.geometry.coordinates.reverse()
}

export function Utf8ArrayToStr(array) {
  var out, i, len, c
  var char2, char3

  out = ''
  len = array.length
  i = 0
  while (i < len) {
    c = array[i++]
    switch (c >> 4) {
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        // 0xxxxxxx
        out += String.fromCharCode(c)
        break
      case 12: case 13:
        // 110x xxxx 10xx xxxx
        char2 = array[i++]
        out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F))
        break
      case 14:
        // 1110 xxxx 10xx xxxx 10xx xxxx
        char2 = array[i++]
        char3 = array[i++]
        out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0))
        break
    }
  }

  return out
}

export function hotColor(d, colors, levelV) {
  const index = levelV.findIndex((item) => item >= d)
  if (index > -1) {
    return colors[index].fill
  } else {
    return colors[colors.length - 1].fill
  }
}

export function sum(arr) {
  return arr.reduce((a, b) =>
    a + b
  , 0)
}

export function average(arr) {
  const sum = arr.reduce((a, b) =>
    a + b
  , 0)
  return sum / arr.length
}

export function boundariesMerge(points, data) {
  const result = points.concat([
    {
      lng: 114.913360,
      lat: 37.4688082,
      val: data
    },
    {
      lng: 114.915404,
      lat: 37.4673265,
      val: data
    },
    {
      lng: 114.913478,
      lat: 37.4658491,
      val: data
    },
    {
      lng: 114.911660,
      lat: 37.4673478,
      val: data
    }
  ])
  return result
}

/**
 * 判断是否为数字
 * @param {Object} val
 */
export function isNumber(val) {
  if (!isNaN(val)) {
    return true
  }
  return false
}
